#include "pyvim.h"

char *
show_bytes(byte *str, int len)
{
	static const char *hexdigits = "0123456789abcdef";
	int i;
	int c;
	char *ret = PyMem_Malloc(len * 4 * len + 3);
	char *p = ret;

	*p++ = '"';
	for (i = 0; i < len; i++) {
		c = str[i];
		*p++ = '\\';
		*p++ = 'x';
		*p++ = hexdigits[(c & 0xf0) >> 4];
		*p++ = hexdigits[c & 0xf];
	}
	*p++ = '"';
	*p = '\0';

	return ret;
}

PyObject *
myprint(PyObject *obj)
{
	PyObject *m, *p;
	if (obj == NULL) {
		printf("(null)\n");
		Py_RETURN_NONE;
	}
	m = PyImport_ImportModule("builtins");
	p = PyObject_CallMethod(m, "print", "O", obj);
	Py_DECREF(m);
	Py_DECREF(p);
	Py_RETURN_NONE;
}

static PyObject *
insert(PyUnicodeObject *self, Py_ssize_t pos, PyUnicodeObject *ins)
{
	PyUnicodeObject *ret;
	Py_ssize_t	len = self->length + ins->length;

	if (pos > self->length)
		pos = self->length;

	ret = (PyUnicodeObject *)PyUnicode_FromUnicode(NULL, len);
	if (ret == NULL)
		return NULL;

	Py_UNICODE_COPY(ret->str, self->str, pos);
	Py_UNICODE_COPY(ret->str + pos, ins->str, ins->length);
	Py_UNICODE_COPY(
		ret->str + pos + ins->length, self->str + pos, self->length - pos);

	return (PyObject *)ret;
}

PyObject *
PyUnicode_Insert(PyObject *self, Py_ssize_t pos, PyObject *ins)
{
	if(!PyUnicode_Check(self)) {
		PyErr_Format(PyExc_ValueError,
			"1st arg type must be str: %R%R", self, self->ob_type);
		return NULL;
	}
	if(!PyUnicode_Check(ins)) {
		PyErr_Format(PyExc_ValueError,
			"2nd arg type must be str: %R%R", ins, self->ob_type);
		return NULL;
	}
	return insert((PyUnicodeObject *)self, pos, (PyUnicodeObject *)ins);
}

/* get the start point of two line intersection area */
int
start_intersection(int s1, int e1, int s2, int e2)
{
	if (s1 >= s2 && s1 <= e2)
		return s1;
	if (s2 >= s1 && s2 <= e1)
		return s2;
	return -1;
}

/* get the start point of two line intersection area */
int
end_intersection(int s1, int e1, int s2, int e2)
{
	if (e1 >= s2 && e1 <= e2)
		return e1;
	if (e2 >= s1 && e2 <= e1)
		return e2;
	return -1;
}

/* get the union of two segments, [*start1, *end1], [start2, end2],
 * start1 and end1 is output also
 * return -1 means two segments is not intersected
 * return 0 means [start2, end2] is included in [*start1, *end1], 
 * start1 and end1 is not changed.
 * return 1 means start1 or end1 is changed
 */
int
seg_union(int *start1, int *end1, int start2, int end2)
{
	if (*start1 <= start2) {
		if (*end1 >= end2)
			return 0;
		else if (*end1 < start2 - 1)
			return -1;
		else {
			*end1 = end2;
			return 1;
		}
	} else {
		if (*start1 > end2 + 1)
			return -1;
		else {
			*start1 = start2;
			*end1 = MAX(*end1, end2);
			return 1;
		}
	}
}

